using UnityEngine;
using System.Collections.Generic;
using System;
using JetBrains.Annotations;
using UBlockly.Scriptable;
using UBlockly.UI;
using UBlockly.Sys;
using UBlockly.Util;
using UBlockly.Compotent;
using UBlockly.Graphic;

namespace UBlockly
{
    public class UBlockEntry
    {
        private int entryHash;
        private UBlocklyPhysic blockPhysic;
        private ISideBarHandler sideBar;
        private IBlockApi runtimeApi;
        private BlockSystem blockSys;
        private PainttingSystem paintSys;
        private WorkSpaceSystem spaceSys;
        private NodeHandlerSystem nodeHanderSys;
        private BlockExtralHandler extralHandler;

        internal UBlocklyPhysic BlockPhysic => blockPhysic;
        internal int EntryHash => entryHash;
        internal BlockSystem BlockSystem => blockSys;
        internal PainttingSystem PaintingSystem => paintSys;
        internal NodeHandlerSystem NodeHandlerSystem => nodeHanderSys;
        public WorkSpaceSystem SpaceSystem => spaceSys;
        public BlockExtralHandler ExtralHandler => extralHandler;
        public ISideBarHandler SideBar => sideBar;

        internal UBlockEntry(UBlocklyPhysic phsicTrans)
        {
            if (phsicTrans == null)
                throw new SystemException("UBlockEntry init error,UBlocklyPhysic is null");
            entryHash = GetHashCode();
            blockPhysic = phsicTrans;
            sideBar = phsicTrans.SideBarHandler;
            blockPhysic.NodeRootTransform.name = Constant.NodeRootTransformName;
            blockSys = new BlockSystem(this);
            paintSys = new PainttingSystem(this);
            spaceSys = new WorkSpaceSystem(this);
            extralHandler = new BlockExtralHandler();
            nodeHanderSys = new NodeHandlerSystem(this, extralHandler);
            blockPhysic.SetUpdater(UpdateDo);
        }

        /// <summary>
        /// 通过api接口批量注册
        /// </summary>
        /// <param name="api"></param>
        public void RegesitBlockApi(IBlockApi api)
        {
            runtimeApi = api;
            ILTranslate.RegistApi(entryHash, runtimeApi);
        }

        public IBlockApi GetRuntimeApi()
        {
            return runtimeApi;
        }

        /// <summary>
        /// 单个api注册
        /// </summary>
        /// <param name="apiName"></param>
        /// <param name="del"></param>
        public void RegesitBlockApi(string apiName, Delegate del)
        {
            ILTranslate.RegistApi(entryHash, apiName, del);
        }

        #region SideBar

        public void InitSiderBar(ClassiflyItem[] classiflyItems, IBlockApi api)
        {
            sideBar.InitClassifly(classiflyItems);
            if (api != null)
            {
                var ll = TranslateHelper.TryParse(api.GetType());
                Dictionary<int, List<Node>> mmmp = new Dictionary<int, List<Node>>();
                foreach (var assit in ll)
                {
                    Node node = BlockGraphic.CreateNode(assit);
                    if (!mmmp.ContainsKey(assit.Classifly))
                        mmmp.Add(assit.Classifly, new List<Node>());
                    mmmp[assit.Classifly].Add(node);
                }

                foreach (var kvp in mmmp)
                {
                    spaceSys.LoadNodes(kvp.Key, kvp.Value);
                }
            }
        }

        public void InitSideBar(ClassiflyItem[] items, List<BlockDescribeData> data)
        {
        }

        #endregion

        #region Space

        public void ClearSpace()
        {
            // _spaceSys.
        }

        public void ClearSideBar()
        {
        }

        #endregion

        #region Node

        public Node CreateSpaceNode(System.Reflection.MethodInfo method, params string[] descs)
        {
            var descData = TranslateHelper.TryParse(0, method, descs);
            var node = BlockGraphic.CreateNode(descData);
            spaceSys.AddToSpace(node);
            return node;
        }

        public Node CreateSpaceNode(string functionDesc, params string[] descs)
        {
            var descData = new BlockDescribeData(functionDesc, 0, descs);
            var node = BlockGraphic.CreateNode(descData);
            spaceSys.AddToSpace(node);
            return node;
        }

        public Node CreateSpaceNode(string functionDefineStr, string[] treeStrArray, params string[] descs)
        {
            var node = BlockGraphic.CreateNode(0,functionDefineStr,treeStrArray,descs);
            spaceSys.AddToSpace(node);
            return node;
        }

        public void CopyNodeFromBlock(BlockObject block)
        {
            var blockGo = GameObject.Instantiate(block.gameObject);
            Node node = BlockGraphic.CreateNode(block);
            spaceSys.AddToSpace(node);
        }

        public bool DeleteNode(Node node)
        {
            return spaceSys.RemoveNode(node);
        }

        /// <summary>
        /// </summary>
        /// <param name="listHead"></param>
        /// <returns></returns>
        public bool DeleteChain(LinkedListNode<Node> listHead)
        {
            return spaceSys.RemoveChain(listHead);
        }

        #endregion

        #region Node Translate

        public void RunNode(Node node, bool asChain = false)
        {
            TranslateHelper.RunNode(this, node, asChain);
        }

        public string TranslateNode(Node node, bool asChain = false)
        {
            return "";
        }

        #endregion

        void UpdateDo()
        {
            paintSys.UpdateDo();
        }
    }
}